package saves;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;

public class GalaxyManager {

    public static final boolean LOAD_ALL_INFO = false;
    private static HashMap<String, HashMap<Integer, Galaxia>> galaxias = new HashMap<>();

    public static Galaxia load(String profile, int codGalaxia, int codSave) throws IOException, ClassNotFoundException {
        if (galaxias.containsKey(profile)) {
            if (galaxias.get(profile).containsKey(codGalaxia))
                return galaxias.get(profile).get(codGalaxia);
        } else
            galaxias.put(profile, new HashMap<Integer, Galaxia>());

        //New galaxy reading with Kryo
        long t1 = System.currentTimeMillis();
        Galaxia g;
        try (Input in = new Input(new FileInputStream(SaveManager.SAVE_PATH + profile + "\\galaxies\\" + codGalaxia + ".dat"))) {
            g = new Kryo().readObject(in, Galaxia.class);
        }

        long t2 = System.currentTimeMillis();
        System.out.println("Galaxy files reading done in " + (t2 - t1) + "ms.");
        galaxias.get(profile).put(codGalaxia, g);

        if (LOAD_ALL_INFO) {
            t1 = System.currentTimeMillis();
            for (int i = 0; i < g.sistemasEstelares.length; i++)
                for (int j = 0; j < g.sistemasEstelares[i].getPlanetas().length; j++)
                    g.sistemasEstelares[i].getPlanetas()[j].loadInfo(SaveManager.SAVE_PATH + profile + "\\saves\\" + codSave + "\\areas\\");
            t2 = System.currentTimeMillis();
            System.out.println("All files reading done in " + (t2 - t1) + "ms.");
        }

        return g;
    }

    public static void unload(String nome, int codigo) {
        galaxias.get(nome).remove(codigo);
    }

    public static void saveAllInfo(String nome, int codFalaxia, int codSave) {
        String path = SaveManager.SAVE_PATH + nome + "\\saves\\" + codSave + "\\areas\\";
        new File(path).mkdirs();
        SistemaEstelar[] ses = galaxias.get(nome).get(codFalaxia).getEstrelas();
        for (int i = 0; i < ses.length; i++)
            for (int j = 0; j < ses[i].getPlanetas().length; j++)
                ses[i].getPlanetas()[j].saveInfo(path);
    }

    private static int getNextCodeFor(String profile) {
        int codigo = 0;
        File f = new File(SaveManager.SAVE_PATH + profile + "\\galaxies");
        File[] gs = f.listFiles();
        if (gs.length != 0) {
            int p = gs.length - 1;
            boolean nfoi = true;
            while (nfoi) {
                try {
                    codigo = Integer.parseInt(gs[p].getName().substring(0, gs[p].getName().length() - 4));
                } catch (Exception e) {
                    continue;
                }
                nfoi = false;
            }
            codigo++;
        }
        return codigo;
    }

    public static int create(String profile, Galaxia g) {
        if (!galaxias.containsKey(profile))
            galaxias.put(profile, new HashMap<Integer, Galaxia>());

        int codigo = 0;
        File f = new File(SaveManager.SAVE_PATH + profile + "\\galaxies");
        if (f.exists())
            codigo = getNextCodeFor(profile);
        else
            f.mkdirs();

        galaxias.get(profile).put(codigo, g);
        try {
            changed(profile, codigo);
        } catch (IOException e) {
            System.err.println("Houve um erro ao tentar salvar o arquivo. Tente novamente mais tarde.");
        }
        return codigo;
    }

    public static int changed(String profile, int codigo) throws IOException {
        Kryo k = new Kryo();
        Galaxia g = galaxias.get(profile).get(codigo);
        if (g.usadaEm.size() > 1) {
            codigo = getNextCodeFor(profile);
            galaxias.get(profile).put(codigo, k.copy(g));
        }
        try (Output out = new Output(new FileOutputStream(SaveManager.SAVE_PATH + profile + "\\galaxies\\" + codigo + ".dat"))) {
            k.writeObject(out, g);
        }
        return codigo;
    }
}
